package logger

import (
	"github.com/shiena/ansicolor"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"gopkg.in/natefinch/lumberjack.v2"
	"os"
	"runtime"
	"time"
)

//var errorLogger *zap.Logger
var filename string

func init() {
	filename = "logs/logger.log"
}

func SetLogPath(path string) {
	filename = path
}

func GetLogger(name string) *zap.Logger {
	// 动态日志等级
	dynamicLevel := zap.NewAtomicLevel()

	w := zapcore.AddSync(&lumberjack.Logger{
		Filename:   filename, // 输出文件
		MaxSize:    500,      // 日志文件最大大小（单位：MB）
		MaxBackups: 3,        // 保留的旧日志文件最大数量
		MaxAge:     28,       // 保存日期
	})

	highPriority := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
		return lvl >= zapcore.InfoLevel
	})

	var cw zapcore.WriteSyncer
	switch runtime.GOOS {
	case "windows":
		cw = zapcore.AddSync(ansicolor.NewAnsiColorWriter(os.Stdout))
	default:
		cw = os.Stdout
	}

	var core zapcore.Core

	if filename != "" {
		core = zapcore.NewTee(
			// 有好的格式、输出控制台、动态等级
			zapcore.NewCore(zapcore.NewConsoleEncoder(newEncoderConfig()), cw, dynamicLevel),
			// json格式、输出文件、处定义等级规则
			zapcore.NewCore(zapcore.NewJSONEncoder(zap.NewDevelopmentEncoderConfig()), w, highPriority),
		)
	} else {
		core = zapcore.NewTee(
			// 有好的格式、输出控制台、动态等级
			zapcore.NewCore(zapcore.NewConsoleEncoder(newEncoderConfig()), cw, dynamicLevel),
		)
	}

	// 开启开发模式，堆栈跟踪
	caller := zap.AddCaller()
	// 开启文件及行号
	development := zap.Development()
	// 设置初始化字段
	//filed := zap.Fields(zap.String("Service", name))
	// 构造日志
	logger := zap.New(core, caller, development).Named(name)

	//errorLogger = zap.New(core, zap.AddCaller())
	defer func() { _ = logger.Sync() }()

	// 将当前日志等级设置为Debug
	// 注意日志等级低于设置的等级，日志文件也不分记录
	dynamicLevel.SetLevel(zap.DebugLevel)
	//errorLogger = logger

	return logger
}

//
//// InitLogger 日志格式初始化
//func InitLogger(filename string) {
//	// 动态日志等级
//	dynamicLevel := zap.NewAtomicLevel()
//
//	w := zapcore.AddSync(&lumberjack.Logger{
//		Filename:   filename, // 输出文件
//		MaxSize:    500,      // 日志文件最大大小（单位：MB）
//		MaxBackups: 3,        // 保留的旧日志文件最大数量
//		MaxAge:     28,       // 保存日期
//	})
//
//	highPriority := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
//		return lvl >= zapcore.InfoLevel
//	})
//
//	var cw zapcore.WriteSyncer
//	switch runtime.GOOS {
//	case "windows":
//		cw = zapcore.AddSync(ansicolor.NewAnsiColorWriter(os.Stdout))
//	default:
//		cw = os.Stdout
//	}
//
//	core := zapcore.NewTee(
//		// 有好的格式、输出控制台、动态等级
//		zapcore.NewCore(zapcore.NewConsoleEncoder(newEncoderConfig()), cw, dynamicLevel),
//		// json格式、输出文件、处定义等级规则
//		zapcore.NewCore(zapcore.NewJSONEncoder(zap.NewDevelopmentEncoderConfig()), w, highPriority),
//	)
//
//	// 开启开发模式，堆栈跟踪
//	caller := zap.AddCaller()
//	// 开启文件及行号
//	development := zap.Development()
//	// 设置初始化字段
//	filed := zap.Fields(zap.String("serviceName", "serviceName"))
//	// 构造日志
//	errorLogger = zap.New(core, caller, development, filed)
//
//	//errorLogger = zap.New(core, zap.AddCaller())
//	defer func() { _ = errorLogger.Sync() }()
//
//	// 将当前日志等级设置为Debug
//	// 注意日志等级低于设置的等级，日志文件也不分记录
//	dynamicLevel.SetLevel(zap.DebugLevel)
//
//	errorLogger.Info("初始化日志打印组件", zap.String("LogPath", filename), zap.String("Te", "dd"))
//}
//
// 格式化时间
func timeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
	enc.AppendString(t.Format("2006-01-02 15:04:05.000"))
}

func newEncoderConfig() zapcore.EncoderConfig {
	return zapcore.EncoderConfig{
		// Keys can be anything except the empty string.
		TimeKey:        "T",                              // json时时间键
		LevelKey:       "L",                              // json时日志等级键
		NameKey:        "N",                              // json时日志记录器名
		MessageKey:     "M",                              // json时日志消息键
		CallerKey:      "C",                              // json时日志文件信息键
		StacktraceKey:  "S",                              // json时堆栈键
		LineEnding:     zapcore.DefaultLineEnding,        // 友好日志换行符
		EncodeLevel:    zapcore.CapitalColorLevelEncoder, // 友好日志等级名大小写（info INFO）
		EncodeTime:     timeEncoder,                      // 友好日志时日期格式化
		EncodeDuration: zapcore.StringDurationEncoder,    // 时间序列化
		EncodeCaller:   zapcore.ShortCallerEncoder,       // 日志文件信息（包/文件.go:行号）
		EncodeName:     zapcore.FullNameEncoder,          // name
	}
}

//
//
//// Debug 打印Debug级别日志
//func Debug(msg string, fields ...zapcore.Field) {
//	errorLogger.Debug(msg, fields...)
//}
//
//// Info 打印Info级别日志
//func Info(msg string, fields ...zapcore.Field) {
//	errorLogger.Info(msg, fields...)
//}
//
//// Infof 打印Info级别日志
//func Infof(format string, a ...interface{}) {
//	errorLogger.Info(fmt.Sprintf(format, a...))
//}
//
//// Panicln 打印Panic级别日志
//func Panicln(msg string, fields ...zapcore.Field) {
//	errorLogger.Panic(msg, fields...)
//}
//
//// Fatalln 打印Fatal级别日志
//func Fatalln(msg string, fields ...zapcore.Field) {
//	errorLogger.Fatal(msg, fields...)
//}
//
//// func Debugf(template string, args ...interface{}) {
//// 	errorLogger.Debugf(template, args...)
//// }
//
//// func Info(args ...interface{}) {
//// 	errorLogger.Info(args...)
//// }
//
//// func Infof(template string, args ...interface{}) {
//// 	errorLogger.Infof(template, args...)
//// }
//
//// func Warn(args ...interface{}) {
//// 	errorLogger.Warn(args...)
//// }
//
//// func Warnf(template string, args ...interface{}) {
//// 	errorLogger.Warnf(template, args...)
//// }
//
//// Error 打印Error级别日志
//func Error(msg string, fields ...zapcore.Field) {
//	errorLogger.Error(msg, fields...)
//}
//
////// Errorf 打印Info级别日志
////func Errorf(format string, a ...interface{}) {
////	errorLogger.Error(fmt.Sprintf(format, a...))
////}
//
//// func DPanic(args ...interface{}) {
//// 	errorLogger.DPanic(args...)
//// }
//
//// func DPanicf(template string, args ...interface{}) {
//// 	errorLogger.DPanicf(template, args...)
//// }
//
//// func Panic(args ...interface{}) {
//// 	errorLogger.Panic(args...)
//// }
//
//// func Panicf(template string, args ...interface{}) {
//// 	errorLogger.Panicf(template, args...)
//// }
//
//// func Fatal(args ...interface{}) {
//// 	errorLogger.Fatal(args...)
//// }
//
//// func Fatalf(template string, args ...interface{}) {
//// 	errorLogger.Fatalf(template, args...)
//// }
